package com.btpj.hospital_server.service;

import cn.hutool.core.date.DateUtil;
import com.btpj.hospital_server.dto.param.UserMedicalCardParam;
import com.btpj.hospital_server.entity.PowerAccount;
import com.btpj.hospital_server.entity.UserMedicalCard;
import com.btpj.hospital_server.entity.UserMedicalCardRelation;
import com.btpj.hospital_server.mapper.UserMedicalCardMapper;
import com.btpj.hospital_server.mapper.UserMedicalCardRelationMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class UserMedicalCardService {

    @Resource
    private UserMedicalCardMapper userMedicalCardMapper;

    @Resource
    private UserMedicalCardRelationMapper userMedicalCardRelationMapper;

    @Resource
    private PowerAccountService powerAccountService;

    /**
     * 获取就诊卡列表
     *
     * @param name   就诊人姓名
     * @param phone  就诊人手机号
     * @param gender 就诊人性别（1：男、2：女）
     * @return 就诊卡列表
     */
    public List<UserMedicalCard> getCardList(String name, String phone, Integer gender) {
        return userMedicalCardMapper.selectByNameOrPhoneOrGender(name, phone, gender);
    }

    /**
     * 获取当前用户绑定的就诊卡列表
     *
     * @return 当前用户绑定的就诊卡列表
     */
    public List<UserMedicalCard> getMyCardList() {
        List<UserMedicalCardRelation> relations = userMedicalCardRelationMapper.selectByAccountId(getCurrentLoginUserId());
        List<UserMedicalCard> userMedicalCards = new ArrayList<>();
        for (UserMedicalCardRelation relation : relations) {
            userMedicalCards.add(userMedicalCardMapper.selectByPrimaryKey(relation.getCardId()));
        }
        return userMedicalCards;
    }

    /**
     * 获取当前登录的账户ID
     *
     * @return 当前登录的账户ID
     */
    private Long getCurrentLoginUserId() {
        PowerAccount userInfo = powerAccountService.getUserInfo();
        assert userInfo != null;
        return userInfo.getId();
    }

    /**
     * 获取当前登录账号绑定的就诊卡数量
     *
     * @return 当前登录账号绑定的就诊卡数量
     */
    public int getCardCountByAccountId() {
        return userMedicalCardRelationMapper.selectByAccountId(getCurrentLoginUserId()).size();
    }

    /**
     * 获取就诊卡表中存在的指定证件号的就诊卡
     *
     * @param identificationNumber 指定就诊卡的证件号
     * @return null表示不存在，存在返回该就诊卡
     */
    private UserMedicalCard getCardByIdentificationNumber(String identificationNumber) {
        return userMedicalCardMapper.selectByIdentificationNumber(identificationNumber);
    }

    /**
     * 判断账号就诊卡关联表中是否存在指定的账号ID与就诊卡ID的数据
     *
     * @param cardId 就诊卡ID
     * @return 账号就诊卡关联表中是否存在指定的账号ID与就诊卡ID的数据
     */
    public boolean existRelation(Long cardId) {
        return userMedicalCardRelationMapper.selectByAccountIdAndCardId(getCurrentLoginUserId(), cardId) != null;
    }

    /**
     * 当前登录账号下是否已经绑定指定证件号的就诊卡
     *
     * @param identificationNumber 证件号
     * @return 账号下是否已经绑定指定证件号的就诊卡
     */
    public boolean exist(String identificationNumber) {
        UserMedicalCard card = getCardByIdentificationNumber(identificationNumber);
        if (card == null) {
            return false;
        } else {
            return existRelation(card.getId());
        }
    }

    /**
     * 就诊卡表中是否存在指定编号的就诊卡
     *
     * @param cardId 就诊卡编号
     * @return 就诊卡表中是否存在指定编号的就诊卡
     */
    public boolean exist(Long cardId) {
        return userMedicalCardMapper.selectByPrimaryKey(cardId) != null;
    }

    /**
     * 添加就诊卡
     *
     * @param param 就诊卡参数
     * @return 是否添加成功
     */
    @Transactional
    public boolean addCard(UserMedicalCardParam param) {
        UserMedicalCard card = getCardByIdentificationNumber(param.getIdentificationNumber());
        UserMedicalCardRelation relation = new UserMedicalCardRelation();
        if (card == null) {
            UserMedicalCard userMedicalCard = new UserMedicalCard();
            BeanUtils.copyProperties(param, userMedicalCard);
            userMedicalCard.setGmtCreate(new Date());
            userMedicalCard.setGmtModified(new Date());
            userMedicalCardMapper.insertSelective(userMedicalCard);
            card = getCardByIdentificationNumber(param.getIdentificationNumber());
            if (card != null) {
                relation.setAccountId(getCurrentLoginUserId());
                relation.setCardId(card.getId());
                relation.setType(param.getType());
                relation.setGmtCreate(new Date());
                relation.setGmtModified(new Date());
                return userMedicalCardRelationMapper.insert(relation) > 0;
            }
            return false;
        } else {
            relation.setAccountId(getCurrentLoginUserId());
            relation.setCardId(card.getId());
            relation.setType(param.getType());
            relation.setGmtCreate(new Date());
            relation.setGmtModified(new Date());
            return userMedicalCardRelationMapper.insert(relation) > 0;
        }
    }

    /**
     * 修改就诊卡信息
     *
     * @param cardId 就诊卡编号
     * @param param  就诊卡参数
     * @return 是否修改成功
     */
    public boolean updateCard(Long cardId, UserMedicalCardParam param) {
        UserMedicalCard userMedicalCard = new UserMedicalCard();
        BeanUtils.copyProperties(param, userMedicalCard);
        userMedicalCard.setId(cardId);
        userMedicalCard.setGmtModified(new Date());
        return userMedicalCardMapper.updateByPrimaryKey(userMedicalCard) > 0;
    }

    /**
     * 获取就诊卡信息
     *
     * @param cardId 就诊卡编号
     * @return 就诊卡信息
     */
    public UserMedicalCard getCardDetail(Long cardId) {
        return userMedicalCardMapper.selectByPrimaryKey(cardId);
    }

    /**
     * 删除就诊卡信息
     *
     * @param cardId 就诊卡编号
     * @return 是否删除成功
     */
    public boolean deleteCard(Long cardId) {
        UserMedicalCardRelation relation = userMedicalCardRelationMapper.selectByAccountIdAndCardId(getCurrentLoginUserId(), cardId);
        return userMedicalCardRelationMapper.deleteByPrimaryKey(relation.getId()) > 0;
    }
}
